<template>

  <div class="base-page-content" id="container" style="z-index: 0;"
       v-loading="lazyLoading.lock"
       :element-loading-text="lazyLoading.text"
       :element-loading-spinner="lazyLoading.icon"
       :element-loading-background="lazyLoading.background"
  ></div>

</template>
<script>
  import * as THREE from "@/components/THREE_JS/three";
  import { OBJLoader, MTLLoader } from '@/components/THREE_JS/three-obj-mtl-loader';
  import { CSS2DRenderer, CSS2DObject } from '@/components/THREE_JS/three-css2drender';
  import { listMesh } from '@/api/slope/mesh';
  import bus from './sendMsg.js';
  import { listSensorConfiguration, indexListSensorCon } from "@/api/page/device.js";

  const OrbitControls = require('three-orbit-controls')(THREE);
  export default {
    name: "threeMap",
    props: {
      modelName: ''
    },
    data() {
      return {
        scene: "",
        labelRenderer: "",
        light: "",
        camera: "",
        controls: "",
        renderer: "",
        geometry: "",
        material: "",
        cube: "",
        fov: 60,
        biaozhudiv: "",
        img: "",
        biaozhuLabel: "",
        threeModelMtl: undefined,
        threeModelObj: undefined,
        sphereArr:[],

        lazyLoading: {
          lock: undefined,
          text: undefined,
          fullscreen: undefined,
          icon: undefined,
          background: undefined,
        },
        threeInfo: {
          meshId: "1",  // id
          meshName: 'female2',  // 模型名称
          capture: '',  // 模型截图
          basePath: '',  // 基础路径
          filePath: '',  // 模型文件路径
          materialPath: '',  // 材质文件路径
          otherPath: '',  // 其他文件路径
        },
        equipmentInfo: undefined, // 所有的设备信息
      };
    },
    mounted() {
      this.getMeshList();
    },
    methods: {
      getMeshList() {
        let self = this;
        listMesh(null).then(response => {
          try {
            let model = response.rows[1];
            self.threeInfo = model;
            indexListSensorCon(null).then(data=>{
              self.equipmentInfo = data.rows;
              self.initScene();
              self.addObj();
              self.animate();
            });
          } catch {

          } finally {
            console.log(self.threeInfo);
          }
        });
      },
      initScene() {
        let self = this;
        self.lazyLoading.lock = true;
        self.lazyLoading.text = '加载模型中';
        self.lazyLoading.fullscreen = false;
        self.lazyLoading.icon = 'el-icon-loading';
        self.lazyLoading.background = 'rgba(0, 0, 0, 0.7)';

        self.scene = new THREE.Scene();
        self.scene.add(new THREE.AmbientLight(0x999999)); //环境光
        self.light = new THREE.DirectionalLight(0xdfebff, 0.45); //从正上方（不是位置）照射过来的平行光，0.45的强度
        self.light.position.set(0, 100, 100);
        self.light.position.multiplyScalar(0.3);
        self.scene.add(self.light);

        //初始化相机
        let width = document.querySelector("#container").offsetWidth;
        let height = document.querySelector("#container").offsetHeight;
        self.camera = new THREE.PerspectiveCamera(self.fov, width / height, 1, 1000);
        // self.camera.matrix.set(0.306,0,0.952,0,0.514,0.841,-0.165,0,-0.801,0.540,0.258,0,-29.326,28.413,60.682,1);
        self.camera.position.set(-80,50,100) ;
        self.camera.lookAt(self.scene.position);
        // self.camera.up.x=0;
        // self.camera.up.y=1;
        // self.camera.up.z=0;
        // self.camera.lookAt(100,100,0);
        //渲染
        self.renderer = new THREE.WebGLRenderer({alpha: true}); //会在body里面生成一个canvas标签,
        self.renderer.setPixelRatio(window.devicePixelRatio); //为了兼容高清屏幕
        // self.renderer.setSize(window.innerWidth-80-24-24, window.innerHeight-60-24-24);
        self.renderer.setSize(width, height);
        const container = document.getElementById('container');
        container.appendChild(self.renderer.domElement);

        //标注渲染
        self.labelRenderer = new CSS2DRenderer();
        self.labelRenderer.setSize(width, height);
        // self.labelRenderer.setSize(window.innerWidth-80-24-24, window.innerHeight-60-24-24);

        self.labelRenderer.domElement.style.position = 'absolute';
        self.labelRenderer.domElement.style.top = 0;
        container.appendChild(self.labelRenderer.domElement);

        //初始化控制器
        self.controls = new OrbitControls(self.camera,container);
        self.controls.target.set(0, 0, 0);
        self.controls.minDistance = 20;
        self.controls.maxDistance = 300;
        self.controls.maxPolarAngle = Math.PI / 2;
        self.controls.update();
        window.addEventListener('resize', self.onWindowResize, false); //添加窗口监听事件（resize-onresize即窗口或框架被重新调整大小）
        // window.addEventListener('mousedown',self.onMyMouseDown);    //模型拾取
      },
      onWindowResize() {
        var width = document.querySelector("#container").offsetWidth;
        var height = document.querySelector("#container").offsetHeight;
        this.camera.aspect = width / height;
        // this.camera.updateProjectionMatrix();
        this.renderer.setSize(width, height);
        this.labelRenderer.setSize(width, height);
      },
      onMyMouseDown(event){
        let self=this;
        var mouse = new THREE.Vector2();
        var rect = self.renderer.domElement.getBoundingClientRect();
        mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
        mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
        let standardVector=new THREE.Vector3(mouse.x,mouse.y,1);
        let worldVector=standardVector.unproject(self.camera);
        let ray=worldVector.sub(self.camera.position).normalize();
        let rayCaster=new THREE.Raycaster(self.camera.position,ray);
        let intersects = rayCaster.intersectObjects(self.scene.children,true);//参数需为数组
        console.log(self.camera.position);
      },

      animate() {
        requestAnimationFrame(this.animate);
        this.render();
      },
      render() {
        this.renderer.render(this.scene, this.camera);
        this.labelRenderer.render(this.scene, this.camera);
      },

      addObj() {
        //包含材质
        let self = this;
        self.threeModelMtl = new MTLLoader().setPath(self.threeInfo.basePath).load(self.threeInfo.materialPath, materials => {
          materials.preload();
          self.materials = materials;
          self.threeModelObj = new OBJLoader().setMaterials(materials).setPath(self.threeInfo.basePath).load(self.threeInfo.filePath, obj => {
            obj.scale.set(1, 1, 1);
            obj.position.set(-70, 30, 0);
            //
            console.log(self.equipmentInfo);
            self.equipmentInfo.forEach(element => {
              let clickMsg = element.sensorId;
              let jsonResult = JSON.parse(element.device.paramValues);
              if (jsonResult!=null) {
                let coordinate = jsonResult.monitor.threeDimensionalCoordinate;
                let x = coordinate.x; // x
                let y = coordinate.y; // y
                let z = coordinate.z; // z
                let pictureUrl = undefined; // 图片路径

                let alarmLevel = 0; // 告警最高等级
                if (element.device.state == 1) {
                  element.monitorItems.forEach(e => {
                    let currentValue = 0; // 当前等级
                    let current = Math.abs(e.itemValue); // 当前值
                    let value1 = e.threshold1; // 阈值1
                    let value2 = e.threshold2; // 阈值2
                    let value3 = e.threshold3; // 阈值3
                    if (current < value1) {
                      currentValue = 0;
                    } else if (current >= value1 && current < value2) {
                      currentValue = 1;
                    } else if (current >= value2 && current < value3) {
                      currentValue = 2;
                    } else if (current >= value3) {
                      currentValue = 3;
                    }
                    if (alarmLevel < currentValue) {
                      alarmLevel = currentValue;
                    }
                  });
                } else if (alarmLevel = element.device.state == 0) {
                  alarmLevel = 4;
                } else if (alarmLevel = element.device.state == 2) {
                  alarmLevel = 5;
                }

                switch(element.sensorType.sensorTypeId) {
                  // todo 可能会根据告警级别显示
                  case 0:
                    pictureUrl = require('@/assets/image/markers/0.png');
                    break;
                  case 1:
                    pictureUrl = require('@/assets/image/markers/1-'+alarmLevel+'.png');
                    break;
                  case 2:
                    pictureUrl = require('@/assets/image/markers/2-'+alarmLevel+'.png');
                    break;
                  case 3:
                    pictureUrl = require('@/assets/image/markers/3-'+alarmLevel+'.png');
                    break;
                  default:
                    pictureUrl = '';
                    break;
                }
                // let sphere= self.addSphere(x,y,z);
                self.addSprite(x, y, z, pictureUrl, 0, element.device.deviceName, obj, clickMsg, () => {});
              }
            });

            // bus.$on('toThreeMsg', data => {});
            self.scene.add(obj);
            // this.fullscreenLoading.close();
            self.lazyLoading.lock = false;

          });
        });
      },
      // x y z 图片地址 偏移量 描述 点击传的值
      addSprite(x, y, z, image, loc, text, Mesh, clickMsg, callback) {
        let self = this;
        //添加div标签
        self.biaozhudiv = document.createElement('div');

        let containerDiv=document.createElement('div');
        let divHtml="<div class='biaozhudiv'><img style='width:25px' src='"+image+"'><div class='three-model-text'>"+text+"</div></div>"
        containerDiv.innerHTML=divHtml;
        self.biaozhudiv.appendChild(containerDiv);

        let imgHtml = containerDiv.children[0].children[0];

        //标注的样式
        // self.biaozhudiv.id = 'biaozhu';
        imgHtml.onclick = function() {
          // self.controls.enabled = false;
          let list = [];
          list.push (clickMsg);

          //昨天的时间
          var day1 = new Date();
          day1.setTime(day1.getTime() - 24 * 60 * 60 * 1000);
          var start = day1.getFullYear() + "-" + (day1.getMonth() + 1) + "-" + day1.getDate();
          //今天的时间
          var day2 = new Date();
          day2.setTime(day2.getTime());
          var end = day2.getFullYear() + "-" + (day2.getMonth() + 1) + "-" + day2.getDate();
          let time = [start, end];
          let result = {"list": list, "time":time};
          self.$emit("search", result);

          bus.$emit('send', result);
          self.$parent.showPanel = true;
        };
        self.biaozhudiv.style.zIndex= 1;
        self.biaozhudiv.style.color = 'rgb(' + 255 + ',' + 255 + ',' + 255 + ')';
        self.biaozhudiv.style.fontSize = 12 + 'px';
        self.biaozhudiv.style.fontFamily = 'auto';
        self.biaozhudiv.style.cursor = 'pointer';
        self.biaozhudiv.onclick = function () {
          callback(Mesh);
        };
        self.biaozhuLabel = new CSS2DObject(self.biaozhudiv);
        self.biaozhuLabel.position.set(x, y+0.5, z);
        Mesh.add(self.biaozhuLabel);
      },

      addSphere(x,y,z){
        let self=this;
        let sphereGeo=new THREE.SphereGeometry(0.2,10,10);
        let sphereMat = new THREE.MeshLambertMaterial({ color:0x0000AA, wireframe:false });//创建材料
        let sphere=new THREE.Mesh(sphereGeo, sphereMat)
        sphere.position.set(x,y,z);
        self.scene.add(sphere);
        self.sphereArr.push(sphere);
        return sphere;
      },

      // 销毁three 3d 模型
      destroyThreeModel(){
        let self = this;
        try{
          window.removeEventListener('resize', self.onWindowResize, false);
        } catch(error) {
        }
        try {
          self.scene.dispose();
        } catch (error) {
        }
        try {
          self.labelRenderer.dispose();
        } catch (error) {
        }
        try {
          self.camera.dispose();
        } catch (error) {
        }
        try {
          self.controls.dispose();
        } catch (error) {
        }
        try {
          self.renderer.dispose();
        } catch (error) {
        }
        try {
          self.geometry.dispose();
        } catch (error) {
        }
        try {
          self.material.dispose();
        } catch (error) {
        }
        try {
          self.threeModelMtl.dispose();
        } catch (error) {
        }
        try {
          self.threeModelObj.dispose();
        } catch (error) {
        }
        try{
          self.unitSphere.dispose();
        }catch (error) {

        }
        try {
          for(let i=0;i<self.sphereArr.length;++i){
            sphereArr[i].dispose();
          }
          self.sphereArr=[]
        }catch (e) {

        }
      }
    },
  }
</script>
<style scope>
* { touch-action: pan-y; }

  .biaozhudiv{
    text-align: center;
  }
  #container{
    z-index: 90;
  }
  .three-model-text {
    font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
  }
</style>
